home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Microsoft Multimedia Viewer How-To CD
/
Microsoft Multimedia Viewer How-To CD.iso
/
mvsample
/
progsamp
/
katasrch
/
results.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-21
|
18KB
|
614 lines
#include <windows.h>
#include <viewer.h>
#include <stdlib.h>
#include "katasrch.h"
#include "results.h"
#include "mvbtask.h"
/***********************************************************************
* SubmitJumpAddr
*
* Sends a JumpAddr command to the specified Viewer instance.
***********************************************************************/
int SubmitJumpAddr(
VWR vwr, // Handle to a Viewer instance
LONG lAddr) // Topic address to jump to
{
char szCommand[64]; // Command to submit
// Build the JumpAddr command and submit it to Viewer
wsprintf(szCommand,"JumpAddr(%ld)", lAddr);
if(VwrCommand(vwr, NULL, szCommand, FALSE) != vwr)
return KSERR_NOVWR;
else
return 0;
}
/************************************************************************
* DisplayTopic
*
* Displays a topic that was double-clicked in a list box
************************************************************************/
int DisplayTopic(
HTITLE htitle, // Handle to title (from TitleOpen)
VWR vwr, // Viewer identifer (from VwrFromMVB)
LONG lTopicNo) // Topic number
{
LONG lTopicAddr; // Topic address of selection
// Get topic address from title
lTopicAddr = TitleGetInfo(htitle, TTLINF_TOPICADDR, lTopicNo, 0L);
if(lTopicAddr == -1)
return KSERR_DISPLAYGETINFO;
return SubmitJumpAddr(vwr, lTopicAddr);
}
/**********************************************************************
* SetHighlight
*
* Issues a Highlight command for the specified hHighlight and title.
*
**********************************************************************/
void SetHighlight(
VWR vwr, // Handle to Viewer (from VwrFromMVB)
HANDLE hHighlight) // Highlight info (from TopicListFromQuery)
{
char szCmd[24];
wsprintf(szCmd,"Highlight(%u)", hHighlight);
VwrCommand(vwr, NULL, szCmd, FALSE);
}
/**********************************************************************
* AddTopicTitle
*
* Adds a topic title to the Results list box.
*
**********************************************************************/
int AddTopicTitle(
HWND hwndLB, // Results list box handle
HTITLE htitle, // Handle to title
HTLIST htl, // Handle to topic list
LONG lTopic) // Index of topic-list entry to add
{
LONG lRet, lTopicNum;
char szTitle[128];
// Get the topic number
lTopicNum = TopicListLookup(htl, lTopic);
if(lTopicNum == -1)
{
return KSERR_TOPICLOOKUP;
}
// Get the topic title
lRet = TitleGetInfo(htitle, TTLINF_TOPICTITLE, lTopicNum,
(LONG)(LPSTR)szTitle);
if(lRet == -1)
{
// Report error
return KSERR_TOPICGETINFO;
}
SendMessage(hwndLB, LB_ADDSTRING, 0, (LPARAM)(LPSTR)szTitle);
return 0; // Indicate more topics
}
/**************************************************************************
* InitResultsControls
*
* Creates the controls used in the results windows and sets their fonts.
**************************************************************************/
void InitResultsControls(
HWND hwnd, // Handle of results window
HFONT hfont) // Font to use
{
if(hfont)
{
SendDlgItemMessage(hwnd, ID_RESULTS_LIST, WM_SETFONT,
(WPARAM)hfont, TRUE);
SendDlgItemMessage(hwnd, ID_RESULTS_PREVIOUS, WM_SETFONT,
(WPARAM)hfont, TRUE);
SendDlgItemMessage(hwnd, ID_RESULTS_NEXT, WM_SETFONT,
(WPARAM)hfont, TRUE);
}
}
/*************************************************************************
* GetViewerSR
*
* Returns the window handle of the scrolling region or NULL if the
* scrolling region is hidden or clipped out of view
*************************************************************************/
HWND GetViewerSR(VWR vwr)
{
LONG lHwndSR = VwrGetInfo(vwr, GI_HWNDSRMAIN, 0, 0L);
HWND hwndSR = LOWORD(lHwndSR);
if(VwrGetInfo(vwr, GI_BOTADDR, hwndSR, 0L) == -1)
return NULL;
else
return hwndSR;
}
/*************************************************************************
* GetViewerNSR
*
* Returns the window handle of the scrolling region or NULL if the
* non-scrolling region is hidden
*************************************************************************/
HWND GetViewerNSR(VWR vwr)
{
LONG lHwndNSR = VwrGetInfo(vwr, GI_HWNDNSRMAIN, 0, 0L);
if(IsWindowVisible(LOWORD(lHwndNSR)))
return LOWORD(lHwndNSR);
else
return NULL;
}
/***************************************************************************
* JumpPrevHighlight
*
* This function jumps to the first highlight above the visible
* portion of the topic. The function returns zero if successful or
* an error code if it can't jump to a previous highlight.
**************************************************************************/
int JumpPrevHighlight(
VWR vwr, // Handle to Viewer instance
HWND hwndViewer, // Window handle of Viewer app
HANDLE hHighlight) // Handle to highlight structure
{
HWND hwndSR, hwndNSR; // Window handles
LONG lSRTopAddr; // Top address in SR
LONG lNSRBottomAddr; // Bottom address in NSR
LONG lSRNextMatch, lSRNextMatchAddr; // First match after top of SR
LONG lSRFirstMatch, lSRFirstMatchAddr; // First match in topic SR
LONG lLen; // Match length
LONG lCurTopic; // Topic number of current topic
LONG lPrev, lPrevAddr; // Previous match (the goal)
// Get information about the layout of the scrolling region
hwndSR = GetViewerSR(vwr);
if(hwndSR == NULL)
return KSERR_RESIZE_SL;
lCurTopic = VwrGetInfo(vwr, GI_TOPICNO, hwndSR, 0L);
lSRTopAddr = VwrGetInfo(vwr, GI_TOPADDR, hwndSR, 0L);
// Determine the first match following the top of the scrolling region
// window. If the first match is number 0, there is no previous
// highlight to jump to.
lSRNextMatch = HighlightMatchFind(hHighlight, lCurTopic, lSRTopAddr,
&lSRNextMatchAddr, &lLen);
if(lSRNextMatch == 0)
return KSERR_NOPREVIOUS;
// If the NSR is present, do some more checking to see if the first
// match following the top of the scrolling region window is actually
// the first match in the topic's scrolling region.
hwndNSR = GetViewerNSR(vwr);
if(hwndNSR)
{
lNSRBottomAddr = VwrGetInfo(vwr, GI_BOTADDR, hwndNSR, 0L);
lSRFirstMatch = HighlightMatchFind(hHighlight, lCurTopic,
lNSRBottomAddr, &lSRFirstMatchAddr,
&lLen);
if(lSRNextMatch == lSRFirstMatch)
return KSERR_NOPREVIOUS;
}
// If there's no match following the top of the scrolling region
// window, jump to the last highlight in the topic. Otherwise,
// jump to the highlight preceding the top of the scrolling region
// window.
if(lSRNextMatch == -1)
lPrev = HighlightMatchCount(hHighlight, lCurTopic) - 1;
else
lPrev = lSRNextMatch - 1;
HighlightMatchGet(hHighlight, lCurTopic, lPrev, &lPrevAddr, &lLen);
// If there's a previous match, jump to it.
return SubmitJumpAddr(vwr, lPrevAddr);
}
/***************************************************************************
* JumpNextHighlight
*
* This function jumps to the next highlight following the visible
* portion of the topic. The function returns zero if successful or
* an error code if it can't jump to a next highlight.
*
* To calculate the address of the next highlight, we simply find the
* address of the last visible element in the topic and then request
* information for the highlight following that address.
*
**************************************************************************/
int JumpNextHighlight(
VWR vwr, // Handle to Viewer instance
HWND hwndViewer, // Window handle of Viewer app
HANDLE hHighlight) // Handle to highlight structure
{
HWND hwndSR; // Scrolling region handle
LONG lAddrBottom, lAddrNext; // Topic addresses
LONG lNext; // Ordinal of next highlight
LONG lHighlightLength; // Highlight length
LONG lCurTopic; // Topic number of current topic
// Get information about the layout of the scrolling region
hwndSR = GetViewerSR(vwr);
if(hwndSR == NULL)
return KSERR_RESIZE_SL;
lCurTopic = VwrGetInfo(vwr, GI_TOPICNO, hwndSR, 0L);
lAddrBottom = VwrGetInfo(vwr, GI_BOTADDR, hwndSR, 0L);
// Determine the next match following the last topic element in the
// scrolling region window.
lNext = HighlightMatchFind(hHighlight, lCurTopic, lAddrBottom,
&lAddrNext, &lHighlightLength);
if(lNext == -1)
return KSERR_NONEXT;
// If there's a next match, jump to it.
return SubmitJumpAddr(vwr, lAddrNext);
}
/**************************************************************************
*
* DrawResultsIcon
*
* This function draws the minimized Results window dialog box.
*
**************************************************************************/
void DrawResultsIcon(
HWND hwnd) // Handle of results window
{
HICON hicon = LoadIcon(ghModule, MAKEINTRESOURCE(ID_RESULTS_ICON));
PAINTSTRUCT ps;
if(hicon == NULL)
return;
BeginPaint(hwnd, &ps);
DrawIcon(ps.hdc, 0, 0, hicon);
EndPaint(hwnd, &ps);
}
/**************************************************************************
* ResultsDlgProc
*
* Dialog-box procedure for the Results window
*
**************************************************************************/
#define WM_USER_MAKEACTIVE WM_USER+1
BOOL CALLBACK ResultsDlgProc(
HWND hwnd, // Window handle
UINT msg, // Message
WPARAM wParam, // Message parameter
LPARAM lParam) // Message parameter
{
LPVWRINFO lpVwrInfo;
int iRet;
LONG lLBSel, lSelTopic;
switch(msg)
{
case WM_INITDIALOG:
// Retrieve the instance data for this task
lpVwrInfo = GetTaskData(GetCurrentTask());
if(lpVwrInfo == NULL)
{
ShowMessage(GetParent(hwnd), KSERR_NOVWRINFO,
MB_ICONEXCLAMATION);
DestroyWindow(hwnd);
return FALSE;
}
// Tell Viewer to send us our messages
if(lpVwrInfo->uiWMRegDlg)
{
SendMessage(lpVwrInfo->hwndViewer, lpVwrInfo->uiWMRegDlg,
(WPARAM)hwnd, 0L);
}
else
{
ShowMessage(GetParent(hwnd), KSERR_NOVWR,
MB_ICONEXCLAMATION);
DestroyWindow(hwnd);
return FALSE;
}
// Set topic counter to 0
lpVwrInfo->lNextResult = 0;
InitResultsControls(hwnd, lpVwrInfo->hfontDlg);
// Set timer to start retrieval of topic titles. NOTE: to be safe,
// we should test the return value to see if the timer's available.
// If not, we could add all the topics to the results list as one
// operation.
SetTimer(hwnd, 1, 50, NULL);
// Apply the new highlight to the title
SetHighlight(lpVwrInfo->vwr, lpVwrInfo->hHighlight);
SetActiveWindow(hwnd);
return TRUE;
case WM_TIMER:
// Retrieve the instance data for this task
lpVwrInfo = GetTaskData(GetCurrentTask());
if(lpVwrInfo == NULL)
{
ShowMessage(hwnd, KSERR_NOVWRINFO, MB_ICONEXCLAMATION);
KillTimer(hwnd, 1);
break;
}
// If we're done, close the timer
if(lpVwrInfo->lNextResult >= lpVwrInfo->lNumTopics)
{
KillTimer(hwnd, 1);
return TRUE;
}
// Add a topic title. If there are any problems, close the timer
// and the results window
iRet = AddTopicTitle(GetDlgItem(hwnd, ID_RESULTS_LIST),
lpVwrInfo->htitle, lpVwrInfo->htlResults,
lpVwrInfo->lNextResult);
if(iRet)
{
KillTimer(hwnd, 1);
ShowMessage(hwnd, KSERR_CANTCREATERESULTS, MB_ICONEXCLAMATION);
DestroyWindow(hwnd);
return TRUE;
}
if(lpVwrInfo->lNextResult == 0)
SendDlgItemMessage(hwnd, ID_RESULTS_LIST, LB_SETCURSEL, 0, 0L);
lpVwrInfo->lNextResult++;
return TRUE;
case WM_ERASEBKGND:
// Get the screen background for a minimized Results icon.
if(IsIconic(hwnd))
{
DefWindowProc(hwnd, WM_ICONERASEBKGND, wParam, lParam);
return TRUE;
}
return FALSE;
case WM_PAINT:
// Paint the icon for the minimized Results dialog box.
if(IsIconic(hwnd))
{
DrawResultsIcon(hwnd);
}
return FALSE;
case WM_USER_MAKEACTIVE:
SetActiveWindow(hwnd);
return TRUE;
case WM_COMMAND:
switch(wParam)
{
case ID_RESULTS_LIST:
if(HIWORD(lParam) != LBN_DBLCLK)
return TRUE;
lpVwrInfo = GetTaskData(GetCurrentTask());
if(lpVwrInfo == NULL)
{
ShowMessage(hwnd, KSERR_NOVWRINFO, MB_ICONEXCLAMATION);
return TRUE;
}
// Get selected topic from list box
lLBSel = SendMessage(LOWORD(lParam), LB_GETCURSEL, 0, 0L);
// Get topic number from topic list
lSelTopic = TopicListLookup(lpVwrInfo->htlResults, lLBSel);
if(lSelTopic == -1)
{
ShowMessage(hwnd, KSERR_DISPLAYFAILED, MB_ICONEXCLAMATION);
return TRUE;
}
iRet = DisplayTopic(lpVwrInfo->htitle, lpVwrInfo->vwr,
lSelTopic);
if(iRet)
{
ShowMessage(hwnd, KSERR_DISPLAYFAILED, MB_ICONEXCLAMATION);
}
// Get the focus back from Viewer
PostMessage(hwnd, WM_USER_MAKEACTIVE, 0, 0L);
return TRUE;
case ID_RESULTS_NEXT:
// Jump to next highlight in selected topic
lpVwrInfo = GetTaskData(GetCurrentTask());
if(lpVwrInfo == NULL)
{
ShowMessage(hwnd, KSERR_NOVWRINFO, MB_ICONEXCLAMATION);
break;
}
iRet = JumpNextHighlight(lpVwrInfo->vwr, lpVwrInfo->hwndViewer,
lpVwrInfo->hHighlight);
if(iRet)
ShowMessage(hwnd, iRet, MB_ICONEXCLAMATION);
// Get the focus back from Viewer
PostMessage(hwnd, WM_USER_MAKEACTIVE, 0, 0L);
return TRUE;
case ID_RESULTS_PREVIOUS:
// Jump to preceding highlight in selected topic
lpVwrInfo = GetTaskData(GetCurrentTask());
if(lpVwrInfo == NULL)
{
ShowMessage(hwnd, KSERR_NOVWRINFO, MB_ICONEXCLAMATION);
break;
}
iRet = JumpPrevHighlight(lpVwrInfo->vwr, lpVwrInfo->hwndViewer,
lpVwrInfo->hHighlight);
if(iRet)
ShowMessage(hwnd, iRet, MB_ICONEXCLAMATION);
// Get the focus back from Viewer
PostMessage(hwnd, WM_USER_MAKEACTIVE, 0, 0L);
return TRUE;
}
break;
case WM_CLOSE:
// Retrieve the instance data for this task
lpVwrInfo = GetTaskData(GetCurrentTask());
if(lpVwrInfo == NULL)
{
ShowMessage(hwnd, KSERR_NOVWRINFO, MB_ICONEXCLAMATION);
break;
}
// Cancel the highlight. We do this here rather than in WM_DESTROY.
// The DLL destroys the Results window when a new title is being
// loaded--in that case, we don't need to reset the highlight.
SetHighlight(lpVwrInfo->vwr, 0);
DestroyWindow(hwnd);
break;
case WM_DESTROY:
// Retrieve the instance data for this task
lpVwrInfo = GetTaskData(GetCurrentTask());
if(lpVwrInfo == NULL)
{
ShowMessage(hwnd, KSERR_NOVWRINFO, MB_ICONEXCLAMATION);
break;
}
// Clean up the topic list and highlight structures
lpVwrInfo->hwndResults = NULL;
if(lpVwrInfo->htlResults)
{
TopicListDestroy(lpVwrInfo->htlResults);
lpVwrInfo->htlResults = NULL;
}
if(lpVwrInfo->hHighlight)
{
HighlightDestroy(lpVwrInfo->hHighlight);
lpVwrInfo->hHighlight = NULL;
}
// Tell Viewer to stop sending us messages
if(lpVwrInfo->uiWMRegDlg)
{
SendMessage(lpVwrInfo->hwndViewer, lpVwrInfo->uiWMRegDlg,
NULL, 0L);
}
break;
}
return FALSE;
}